Option Strict On
Imports System
Imports System.Diagnostics
Imports System.Drawing
Imports System.Windows.Forms
Imports DevExpress.CodeRush.Core
Imports DevExpress.CodeRush.Diagnostics.General
Imports DevExpress.CodeRush.PlugInCore
Imports DevExpress.CodeRush.StructuralParser
Imports DX_Contrib
Imports DX_Contrib.Painting
Imports SP = DevExpress.CodeRush.StructuralParser

Namespace CR_UnusedVariables
    Public Class UnusedVariablesPlugIn
        Inherits StandardPlugIn
#Region "Standard Plugin Stuff"
#Region " private fields... "
        Private components As System.ComponentModel.IContainer
#End Region

        ' constructor...
#Region " UnusedVariablesPlugIn "
        Public Sub New()
            ''' <summary>
            ''' Required for Windows.Forms Class Composition Designer support
            ''' </summary>
            InitializeComponent()
        End Sub
#End Region

        ' CodeRush-generated code
#Region " InitializePlugIn "
        Public Overrides Sub InitializePlugIn()
            MyBase.InitializePlugIn()

            '
            ' TODO: Add your initialization code here.
            '
            'AddHandler EventNexus.FarCacheChanged, AddressOf FarCacheChanged

            LoadSettings()
        End Sub
#End Region
#Region " FinalizePlugIn "
        Public Overrides Sub FinalizePlugIn()
            '
            ' TODO: Add your finalization code here.
            '
            'RemoveHandler EventNexus.FarCacheChanged, AddressOf FarCacheChanged
            MyBase.FinalizePlugIn()
        End Sub
#End Region

#Region " Component Designer generated code "
        ''' <summary>
        ''' Required method for Designer support - do not modify
        ''' the contents of this method with the code editor.
        ''' </summary>
        Friend WithEvents UnusedVariableCount As DevExpress.CodeRush.Extensions.CodeMetricProvider
        Private Sub InitializeComponent()
            Me.components = New System.ComponentModel.Container
            Me.UnusedVariableCount = New DevExpress.CodeRush.Extensions.CodeMetricProvider(Me.components)
            CType(Me.UnusedVariableCount, System.ComponentModel.ISupportInitialize).BeginInit()
            CType(Me, System.ComponentModel.ISupportInitialize).BeginInit()
            '
            'UnusedVariableCount
            '
            Me.UnusedVariableCount.Description = "Unused Variable Count"
            Me.UnusedVariableCount.DisplayName = "Unused Variable Count"
            Me.UnusedVariableCount.ProviderName = "UnusedVariableCount"
            Me.UnusedVariableCount.Register = True
            Me.UnusedVariableCount.WarningValue = 1
            '
            'UnusedVariablesPlugIn
            '
            CType(Me.UnusedVariableCount, System.ComponentModel.ISupportInitialize).EndInit()
            CType(Me, System.ComponentModel.ISupportInitialize).EndInit()

        End Sub
#End Region
#End Region
#Region "Fields"
        Private DefaultColor As System.Drawing.Color = Color.Red
        Private Const DEFAULT_OPACITY As Integer = 255
        Private mCache As New PaintOptionsCache
        Private DefaultPaintStyle As New PaintOptions(PaintRequestEnum.UnderlineWavy, DefaultColor)
        Private mCurrentPaintStyle As New PaintOptions(PaintRequestEnum.UnderlineWavy, DefaultColor)
        Private Painter As New Painter
        Private mParsing As Boolean = False
#End Region
#Region "Readonly Properties"
        Private ReadOnly Property Cache() As PaintOptionsCache
            Get
                If mCache Is Nothing Then
                    mCache = New PaintOptionsCache
                End If
                Return mCache
            End Get
        End Property
#End Region
#Region "UI Events"
        Private Sub UnusedVariablesPlugIn_AfterParse(ByVal ea As DevExpress.CodeRush.Core.AfterParseEventArgs) Handles MyBase.AfterParse
            Try
                Log.SendMsg("Deleting Invalid Cache Items")
                DeleteInvalidCacheItems(ea.DeletedNodes)
                If ea.ParseType = ParseType.Full Then
                    'Invoker.InvokeMethod(AddressOf ParseEntireFile, AddressOf RefreshTextViews)
                    Call ParseEntireFile()
                    Call Editor.InvalidateAllTextViews()
                Else
                    Log.SendMsg("Partial Parse")
                    mParsing = True
                    ParseChildNodes(ea.ParseResult)
                    mParsing = False
                    Call Editor.InvalidateAllTextViews()
                    SaveDocumentCache()
                End If
            Catch ex As Exception
                Debug.WriteLine(ex.Message)
                Throw
            End Try
        End Sub
        Private Sub UnusedVariablesPlugIn_EditorPaintLanguageElement(ByVal ea As DevExpress.CodeRush.Core.EditorPaintLanguageElementEventArgs) Handles MyBase.EditorPaintLanguageElement
            If Cache.Contains(ea.LanguageElement) Then
                Call Painter.PaintLanguageElementPaintOptions(Cache.Item(ea.LanguageElement), ea.PaintArgs)
            End If
        End Sub
        Private Sub UnusedVariablesPlugIn_DocumentActivated(ByVal ea As DevExpress.CodeRush.Core.DocumentEventArgs) Handles MyBase.DocumentActivated
            mCache = Caching.GetCacheFromDocument(CType(ea.Document, TextDocument), "UnusedVarCache")
        End Sub
        'Private Sub UnusedVariableCount_GetMetricValue(ByVal sender As System.Object, ByVal e As DevExpress.CodeRush.Extensions.GetMetricValueEventArgs) Handles UnusedVariableCount.GetMetricValue
        '    If e.LanguageElement.ElementType = LanguageElementType.Method Then
        '        Dim Score As Integer = 0
        '        Dim Method As Method = CType(e.LanguageElement, Method)
        '        For Each LE As LanguageElement In Method.AllParameters
        '            If isUnused(LE) Then
        '                Score += 1
        '            End If
        '        Next
        '        For Each LE As LanguageElement In Method.AllVariables
        '            If isUnused(LE) Then
        '                Score += 1
        '            End If
        '        Next
        '        e.Value = Score
        '    End If
        'End Sub
#End Region
#Region "Cache Item Deletion"
        Private Sub DeleteInvalidCacheItems(ByVal DeletedNodes As LanguageElementCollection)
            If Not DeletedNodes Is Nothing Then
                For Each Node As LanguageElement In DeletedNodes
                    DeleteItemFromCache(Node)
                Next
            End If
        End Sub
        Private Sub DeleteItemFromCache(ByVal Node As LanguageElement)
            mCache.Remove(Node)
        End Sub
#End Region
#Region "Parse"
        Private Sub ParseEntireFile()
            Log.SendMsg("Full Parse")
            Call StartTimer("AllFileRefresh")
            Dim FoundNodes As LanguageElementCollection = GetAllVars()
            Debug.WriteLine(String.Format("Found {0} Nodes", FoundNodes.Count))
            AddQualifyingNodesFrom(FoundNodes)
            Call StopTimer("AllFileRefresh")
        End Sub
        Private Sub ParseChildNodes(ByVal LE As LanguageElement)
            Call StartTimer("PartialRefresh")
            Dim FoundNodes As LanguageElementCollection = NodeCollector.CreateCollectorDeep(UsableTypes).Collect(LE)
            Debug.WriteLine(String.Format("Found {0} Nodes", FoundNodes.Count))
            AddQualifyingNodesFrom(FoundNodes)
            Call StopTimer("PartialRefresh")
        End Sub
#End Region
#Region "SaveCacheAndRefresh"
        Private Sub SaveCacheAndRefresh()
            SaveDocumentCache()
            Call Editor.InvalidateAllTextViews()
        End Sub
        Private Sub SaveDocumentCache()
            Log.SendMsg("Saving Cache")
            Caching.SaveCacheToDocument(CodeRush.Documents.ActiveTextDocument, _
                                        mCache, _
                                        "UnusedVarCache")
        End Sub
#End Region
#Region "GetNodes"
        Private Function GetAllVars() As LanguageElementCollection
            Try
                Dim SourceFile As SourceFile = GetActiveSourceFile()
                If SourceFile Is Nothing Then
                    Exit Function
                End If
                Dim Nodes As New LanguageElementCollection
                For Each Type As TypeDeclaration In SourceFile.AllTypes
                    For Each Field As BaseVariable In Type.AllVariables
                        Nodes.Add(Field)
                    Next
                    For Each Method As Method In Type.AllMethods
                        For Each Var As Variable In Method.AllVariables
                            Nodes.Add(Var)
                        Next
                        For Each Param As Param In Method.AllParameters
                            Nodes.Add(Param)
                        Next
                        'Nodes.Add(Method)
                    Next
                Next
                Return Nodes
            Catch ex As Exception
                Debug.WriteLine(ex.Message)
                Throw
            End Try
        End Function
#End Region
#Region "ProcessMethod"
        Private Sub AddQualifyingNodesFrom(ByVal Nodes As LanguageElementCollection)
            Log.SendMsg(String.Format("Found {0} Nodes ... Parsing...", Nodes.Count))
            For Each Node As LanguageElement In Nodes
                Call TryAdd(Node)
            Next
            Log.SendMsg("Nodes Processed")
        End Sub
        Private Sub TryAdd(ByVal LE As LanguageElement)
            If LE Is Nothing Then
                Exit Sub
            End If
            If isUnused(LE) Then
                Call mCache.Add(LE, mCurrentPaintStyle)
            End If
        End Sub
#End Region
#Region "Options"
        Private Sub UnusedVariablesPlugIn_OptionsChanged(ByVal ea As DevExpress.CodeRush.Core.OptionsChangedEventArgs) Handles MyBase.OptionsChanged
            If (ea.OptionsPages.Contains(GetType(OptUnusedVariables))) Then
                LoadSettings()
            End If
        End Sub
        Private Sub LoadSettings()
            Dim Storage As DecoupledStorage = OptUnusedVariables.Storage
            LoadStyle(Storage, "Options", "Unused", mCurrentPaintStyle, DefaultPaintStyle)
            Storage.Dispose()
            mCache = Nothing
        End Sub
#End Region

    End Class
End Namespace
